package com.settlement.system.common.util.common;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

/**
 * 线程池工具类
 *
 * @author Ximi
 * @since 2020/12/09
 */
@Slf4j
@Component
public class AcsThreadPoolUtils implements DisposableBean {

    private static ExecutorService executorService;

    /**
     * 核心线程数。CPU总线程数的2倍。
     */
    private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;

    /**
     * 最大线程数（基本用不到，用到的时候，说明缓存队列不够了，程序即将抛出异常）
     */
    private static final int MAXIMUM_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 4;

    /**
     * 等待时间
     */
    private static final long KEEP_ALIVE_TIME = 0L;

    /**
     * 缓存任务的队列容量
     */
    private static final int QUEUE_CAPACITY = 1024*10;

    /**
     * 线程名称前缀
     */
    private static final String THREAD_NAME_FORMAT = "acs-pool-thread-%d";

    //private static final String threadNamePrefix = "acs-thread-";


    public static ExecutorService getExecutorService() {
        if (executorService == null) {
            synchronized (AcsThreadPoolUtils.class) {
                if (executorService == null) {
                    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                            .setNameFormat(THREAD_NAME_FORMAT).build();
                    executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE,
                            KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(QUEUE_CAPACITY), namedThreadFactory,
                            new ThreadPoolExecutor.AbortPolicy());
                    /*executorService = Executors.newFixedThreadPool(8,
                            new CustomizableThreadFactory("acs-thread-"));*/
                }
            }
        }
        return executorService;
    }

    @Override
    public void destroy() throws Exception {
        if (executorService != null) {
            try {
                if (!executorService.isShutdown()) {
                    executorService.shutdown();
                }
            } catch (Exception ex) {

            }
        }
    }

    public static void main(String[] args) {

    }
}
